<?php
/**
 * @filename Common.php
 * @author anzai <236049524@qq.com>
 * @version 1.0
 * @copyright http://www.judianyun.com 2013
 *
 * Modified at : 2013-2-17 09:28:14
 *
 * 框架内置常用函数库
 *
 */

/**
 * 
 * +------------------------------------------------------------+
 * @name auto_charset
 * +------------------------------------------------------------+
 * 自动转换字符集 支持数组转换
 * 需要 iconv 或者 mb_string 模块支持
 * 如果 输出字符集和模板字符集相同则不进行转换
 * +------------------------------------------------------------+
 * 
 * @param string $value 需要转换的字符串
 * @param string $from 	输出前字符编码
 * @param string $to	输出后字符编码
 * 
 * @return string
 *
 */
function auto_charset($value, $from='gb2312', $to='utf-8'){
    $from =	strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
    $to	  =	strtoupper($to)	  == 'UTF8' ? 'utf-8' : $to;
    
    //如果编码相同或者非字符串标量则不转换
    if( strtoupper($from) === strtoupper($to) || empty($value) || (is_scalar($value) && !is_string($value)) ){
        return $value;
    }
    
    if(is_string($value) ) {
        if(function_exists('mb_convert_encoding')){
            return mb_convert_encoding ($value, $to, $from);
        }elseif(function_exists('iconv')){
            return iconv($from, $to, $value);
        }else{//不支持自动转码
            E::halt(Helper::L('FUNC_A_NOSUPPORT'));
            return $value;
        }
    }elseif(is_array($value)){
        foreach ($value as $key => $val) {
            $_key = auto_charset($key, $from, $to);
            $value[$_key] = auto_charset($val, $from, $to);
            if($key != $_key){
                unset($value[$key]);
            }
        }
        return $value;
    }elseif(is_object($value)){
        $vars = get_object_vars($value);
        foreach($vars as $key=>$val) {
            $value->$key = auto_charset($val, $from, $to);
        }
        return $value;
    }else{
        return $value;
    }
}

/**
 * 
 * +------------------------------------------------------------+
 * @name C
 * +------------------------------------------------------------+
 * 读取或设置配置信息
 * +------------------------------------------------------------+
 *
 * @param mixed $name
 * @param mixed $default
 * @param mixed $value
 *
 */
function C($name,$default=null,$value=null){
	static $config = array();
	if(empty($config)){
		$config = require_once __INCLUDES_PATH__ . 'Conf/Config.php';
		
		is_dir(INCLUDES_PATH) or Helper::mkdir(INCLUDES_PATH);
		
		$myflie =  INCLUDES_PATH . 'my.config.php';
		//用户自定义配置文件不存在则自动创建
		if (!file_exists($myflie)){
			$code = file_get_contents(__INCLUDES_PATH__ . 'Conf/Config.php');
			$code = "<?php\n".substr($code, strpos($code, '//用户可自定义配置文件'));
			Helper::write($myflie, $code);
			unset($code);
		}
		$myconfig = require_once $myflie;
		if (!empty($myconfig) && is_array($myconfig))$config = array_merge($config, $myconfig);
		unset($myconfig, $myflie);
	}
	
	//将用户自定义全局配置信息通框架内置全局配置信息合并，优先使用用户自定义的配置信息
	if (is_array($name)){
		$config = array_merge($config, $name);
		return;
	}
	$tmpname = strpos($name, '.') ? explode('.', $name) : $name;
	
	if ($value===null){//获取配置信息
		if ($default!==null && !isset($config[$name])){
			C($name,null,$default);
		}
		return is_array($tmpname) ? $config[$tmpname[0]][$tmpname[1]] : (isset($config[$name]) ? $config[$name] : null);
	}else//设置配置信息
		is_array($tmpname) ? $config[$tmpname[0]][$tmpname[1]] = $value : $config[$name] = $value;
}

//变量输出
function dump($var)
{
	ob_start();
	var_dump($var);
	$output = ob_get_clean();
	$output = preg_replace('/\]\=\>\n(\s+)/m', "] => ", $output);
	$output = '<pre>'.H($output, ENT_QUOTES, OUT_CHARSET).'</pre>';
    echo $output;
}

//智能合并多个数组
function extend($arr){
	$args = func_get_args();
	$arr = array();
	if (!empty($args)){
		foreach ($args as $vo){
			if ((is_array($vo) && count($vo) > 0) || $vo != ''){
				$vo = is_array($vo) ? $vo : array($vo);
				$arr = array_merge($arr, $vo);
			}
		}
	}
	
	return $arr;
}

/**
 * 
 * +------------------------------------------------------------+
 * @name format_dir
 * +------------------------------------------------------------+
 * 规划化路径名
 * +------------------------------------------------------------+
 * 
 * @param string $pathname
 * 
 */
function format_dir($pathname){
	if ($pathname){
		$pathname = str_replace(array('\\','/./', '/.//'), '/', $pathname . '/');
		$pathname = preg_replace('/\/{2,}/','/', $pathname);
		$pathname = preg_replace('/([^\/\.]+?)\.\/'.'/','\\1/', $pathname);
	}
	return $pathname;
}

//htmlspecialchars的简写
function H($string, $quote=ENT_QUOTES, $charset=OUT_CHARSET){
    if ($quote === true){
        $string = str_replace(array("\r","\n","\t"), '', $string);
        $quote = ENT_QUOTES;
    }
	return htmlspecialchars($string, $quote, $charset);
}

//htmlspecialchars_decode简写
function HD($string){
	return htmlspecialchars_decode($string);
}

//in_array的别名，可智能判断$array是否为数组，不是数组则自动转换为数组
function inArray($needle, $array){
	return in_array($needle, is_array($array) ? $array : array($array));
}

/**
 * 函数M的别名
 */
function D($m=null, $id=null, $table='', $idField='', $dbConfig=null){
	return M($m, $id, $table, $idField, $dbConfig);
}

/**
 * 
 * +------------------------------------------------------------+
 * @name M
 * +------------------------------------------------------------+
 * 实例化一个Model模型类实例
 * +------------------------------------------------------------+
 *
 * @author anzai <236049524@qq.com>
 * @version 1.0
 *
 * @example
 *
 * @param string $m			模型类名，为空表示M本身
 * @param int 	 $id		要加载的数据行ID
 * @param string $table		指定要操作的表
 * @param string $idField	ID字段对应的字段名
 * @param array  $dbConfig	数据库配置
 *
 */
function M($m=null, $id=null, $table='', $idField='', $dbConfig=null){
	$class = empty($m) ? 'Model' : $m . MODEL_SUFFIX;
	static $_m = null, $_mobj = array();
	if (defined('MZ_NOT_STATIC_MODEL')){
	    $_mobj = array();
	}
	
	//若指定类已实例化过，则不再进行实例化
	if (is_object($_mobj[$class]) && $_m == $m){
		$id !== null && $_mobj[$class]->load($id);
		!empty($table) && $_mobj[$class]->setTable($table);
	}else{
		$_m = $m;
		if ($class != 'Model' && !class_exists($class)){
			if (!App::_autoload($class)){
				$class = 'Model';
				$table = C('DB_CONFIG.tablepre') . $m;
			}
			unset($m);
		}
		$_mobj[$class] = new $class($id, $table, $idField, $dbConfig);
	}
	return $_mobj[$class];
}

/**
 * 
 * +------------------------------------------------------------+
 * @name S
 * +------------------------------------------------------------+
 * 获取或设置session，S()表示获取整个$_SESSION
 * +------------------------------------------------------------+
 *
 * @author anzai <236049524@qq.com>
 * @version 1.0
 *
 * @example
 *
 * @param $name 指定获取或设置session的键，默认会加上session前缀
 * @param $value 该值不为null时，表示设置值
 * @param $pre session前缀
 *
 */
function S($name=null, $value=null){
	if($name===null) return $_SESSION;
	$name = md5(APP_NAME . $name);
	if ($value===null) return isset($_SESSION[$name]) ? $_SESSION[$name] : null;
	if ($value===false){
		unset($_SESSION[$name]);
	}else{
		$_SESSION[$name] = $value;
	}
}

function session($name=null, $value=null){
	return S($name, $value);
}

/**
 * 
 * +------------------------------------------------------------+
 * @name cookie
 * +------------------------------------------------------------+
 * 设置和获取cookie
 * +------------------------------------------------------------+
 *
 * @param string $name
 * @param string $value
 * @param number $expire
 * @param string $path
 * @return Ambigous <NULL, unknown>
 *
 */
function cookie($name, $value=null, $expire=5400 ,$path= '/', $domain = ''){
	$name = md5(APP_NAME . $name);
	if ($value === null){
		return isset($_COOKIE[$name]) ? $_COOKIE[$name] : null;
	}
	
	if ($value === false){
		setcookie($name , '', time() - 500000, $path, $domain);
		unset($_COOKIE[$name]);
	}
	else{
		$_COOKIE[$name] = $value;
		setcookie($name , $value, time() + $expire, $path, $domain, null, true);
	}
}

/**
 * 
 * +------------------------------------------------------------+
 * @name url
 * +------------------------------------------------------------+
 * 根据传入不同的参数和启用的url模式自动组装相应的url地址
 * +------------------------------------------------------------+
 *
 * @author anzai <236049524@qq.com>
 * @version 1.0
 *
 * @example
 *
 * @param string $action	动作名，默认为index
 * @param string $module	控制器名，默认为当前当前所在控制器
 * @param mixed  $params	附带参数，格式可以是一个关联数组array(变量名=>值得)，如array('p'=>1,'a='3)；或一个字符串，如p=1&a=3
 * @param string $URL_MODE	url模式
 *
 */
function url($action='', $module='', $params='', $script_name='', $URL_MODE = ''){
	$script = $script_name ?  '/' . $script_name : (defined('_SCRIPT_NAME_') ? _SCRIPT_NAME_ : $_SERVER['SCRIPT_NAME']);
	$action = empty($action) ? DF_ACTION : $action;
	$module = empty($module) ? $GLOBALS['MODULE_NAME'] : $module;
	
	if ($params && is_array($params)){
		//过滤值为空的参数
		$params = filterEmptyArr($params, array(VAR_ACTION, VAR_MODULE));
		$params = !$params ? '' : http_build_query($params);
	}else if (is_array($params)){
		$params = '';
	}
	
	if ($params && substr($params, 0, 1) == '&'){
		$params = substr($params, 1);
	}
	$URL_MODE = $URL_MODE == '' ? C('URL_MODE') : $URL_MODE;
	switch ($URL_MODE){
		case 2://PATHINFO模式
			$split = C('URL_SEPARATOR', '/');
			$url = $module . $split . $action;
			if ($params){
				$params = str_replace(array('=','&'), $split, $params);
				$url .= $split . $params;
			}
			//若有开启伪静态功能，则自动加上定义的伪静态后缀
			$url = 1 == C('PSEUDO_STATIC', 1) ? $url . C('STATIC_SUFFIX', '.html') : $url;
			break;
			
		default://一般模式
			$split = '?';
			$url = VAR_MODULE . '=' . $module.'&' . VAR_ACTION . '=' . $action;
			if ($params != ''){
				$params = str_replace('&amp;', '&', $params);
				$url .= '&' . $params;
			}
	}
	if (true === C('URL_ROUTER_ON', false)){
		//路由伪装
		$rules = C('_ROUTE_RULE_.ENCODE');
		if (!empty($rules) && is_array($rules)){
			foreach ($rules as $regex => $replace){
				$url = preg_replace($regex, $replace, $url);
			}
		}
		unset($rules);
	}
	
	$rewrite = C('REWRITE_MODE', false);
	if ($rewrite){
		$rule = C('REWRITER_RULE','%HOST/%SCRIPTNAME/%PARAMS');
		$url = str_replace(array('%HOST', '%SCRIPTNAME', '%PARAMS'), array(HTTP_DOMAIN, $script, $url), $rule);
	}else{
		//$url = HTTP_DOMAIN . $script . $split . $url;
		$url = $script . $split . $url;
	}
	return $url;
}

/**
 * 
 * +------------------------------------------------------------+
 * @name xaddslashes
 * +------------------------------------------------------------+
 * 为了防止单引号攻击
 * +------------------------------------------------------------+
 *
 * @author anzai <236049524@qq.com>
 * @version 1.0
 *
 * @example
 *
 * @param unknown_type $string
 * @param boolean $force 是否强制行对单引号加上反斜线
 * @param string  $func 自定义数据处理函数
 *
 */
function xaddslashes($string, $force = false,$func=null){
	if(!MAGIC_QUOTES_GPC || $force){
		if(is_array($string)){
			foreach($string as $key => $val){
				$string[$key] = xaddslashes($val, $force, $func);
			}
		}else{
			empty($func) or $string = function_exists($func) ? $func($string) : $string;
			$string = trim($string);
		}
	}
	return $string;
}

//过滤数组为空的元素
function filterEmptyArr($arr, $filterArr = array()){
	if(!is_array($arr)) return $arr;
	foreach ($arr as $key => $value){
		if ($value === '' || (!is_array($value) && inArray($key, $filterArr))){
			unset($arr[$key]);
		}else if (is_array($value)){
			$arr[$key] = filterEmptyArr($arr[$key]);
		}
	}
	
	return $arr;
}
?>